home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 1995 #5 & #6
/
Amiga Plus CD - 1995 - No. 5 and 6.iso
/
tex
/
src
/
flib
/
flib.c
next >
Wrap
C/C++ Source or Header
|
1992-11-04
|
47KB
|
1,874 lines
/*
* Fontlibrary program.
*
* used for our TeX-system to save disk space and for
* speed up the loading of fonts for "ShowDVI" and "DVIprint".
*
* This program is freely redistributable. You may modify and use this
* program to your heart's content, so long as you send modifications
* to Georg Hessmann. It can be included in any distribution, commercial
* or otherwise, so long as the banner string defined in the constant
* HEADER is not modified (except for the version number and the machine
* type) and this banner is printed on program invocation, or can be
* printed on program invocation with the -? option.
*
* For further information read the README file.
*
* 31.01.90 (hes) (C) Copyright 1990/91 Georg Hessmann.
*
* 12.02.90 (hes) v1.01 new flib-format, rename command
* 14.02.90 (rbs) ported to Atari ST
* 25.04.90 (jrb) fixed up for Atari ST gcc
* 05.06.90 (hes) v1.02 little bug fixes, add flib links (hes)
* 08.01.91 (hes) v1.03 add relative flib links
* 03.11.92 (hes) v1.10 add wildcard support (only with Dice/Amiga)
* add two new flags 's' and 'e'
* 's' -- strip path, don't store the path of a font
* 'e' -- strip extension, don't store the extension
*/
/* Is the compiler a ANSI-C compiler */
#ifdef AMIGA
# ifdef LATTICE
# define ANSI
# endif
# ifdef AZTEC_C
# define ANSI
# endif /* AZTEC_C */
# ifdef _DCC
# define ANSI
# endif /* _DCC */
#else
# ifdef ATARI
# ifdef __GNUC__
# define ANSI
# endif /* __GNUC__ */
# endif /* ATARI */
#endif /* AMIGA */
/* standard includes */
#include <stdio.h>
#ifdef ANSI
# include <stdlib.h>
# include <string.h>
# ifdef AMIGA
# ifndef _DCC
# include <dos.h>
# endif /* !_DCC */
# endif /* AMIGA */
# ifdef ATARI
# ifndef __GNUC__
# include <tos.h>
# include <ext.h>
# else
# include <unixlib.h>
# include <fcntl.h>
# define S_IWRITE W_OK
# define S_IREAD R_OK
# endif /* __GNUC__ */
# endif /* ATARI */
#endif /* ANSI */
/* open mode for files */
#ifdef ATARI
# define OPEN_FOR_READING "rb"
# define OPEN_FOR_WRITING "wb"
# define OPEN_FOR_APPEND "rb+"
# ifndef __GNUC__
extern int access(char *, int);
# endif /* __GNUC__ */
#else
# define OPEN_FOR_READING "r"
# define OPEN_FOR_WRITING "w"
# define OPEN_FOR_APPEND "r+"
#endif
/* prototyping on/off */
#ifdef ANSI
# define Args(x) x
#else
# define Args(x) ()
#endif /* ANSI */
#ifdef AZTEC_C
void *malloc Args((unsigned));
void free Args((char *));
char *strchr();
char *strrchr();
#endif /* AZTEC_C */
#ifdef AMIGA
# ifdef LATTICE
# define perror(x) poserr(x)
# endif /* LATTICE */
# ifdef AZTEC_C
# define remove(x) unlink(x)
/* warning: AztecC seems to have problems with the returncode from fseek */
# endif /* AZTEC_C */
#else AMIGA
# ifndef ANSI
# define remove(x) unlink(x)
# endif /* ANSI */
#endif /* AMIGA */
#ifdef ATARI
# include <errno.h>
#else
extern int errno;
#endif
/* Aufbau einer Fontlibrary :
* +---------------------------------------+
* | magic number 4 Bytes |
* | number of direntries 4 Bytes |
* | [flib_dirent]* |
* | [modules]* |
* +---------------------------------------+
*/
/* important constants */
#define OLD_LIBMAGIC 0xA797F033L /* magic number */
#define LIBMAGIC (((long)'F'<<24) | ((long)'L'<<16) | ((long)'I'<<8) | (long)'B')
#define LNKMAGIC (((long)'F'<<24) | ((long)'L'<<16) | ((long)'N'<<8) | (long)'K')
#define FILENAMELEN 14
#define NEWFILENAMELEN 22
#define TMPFLIB "tmpflib.tmp"
#define BUFSIZE 20480
#define DOSNAMESIZE 100
#define MAXLINKLEVELS 20
#ifdef AMIGA
# define MACHINE "AMIGA"
#else
# ifdef ATARI
# define MACHINE "ATARI"
# else
# define MACHINE "UNIX"
# include <sys/file.h>
# define S_IWRITE W_OK
# define S_IREAD R_OK
# endif /* ATARI */
#endif /* AMIGA */
#define VERSION "1.10"
#ifdef ATARI
# define HEADER "FontLib Manager - Version %s for %s \275 1990/91/92 Georg Hessmann/Robert Stabl\n"
#else
# define HEADER "FontLib Manager - Version %s for %s (c) 1990/91/92 Georg Hessmann\n"
#endif
#ifdef AMIGA
static char version[] = "\0$VER: flib 1.10 (11/03/92)";
#endif
#define OLD_VERSION 0
#define NEW_VERSION 1
static char buffer[BUFSIZE]; /* used to copy modules */
#ifndef FALSE
# define FALSE 0
#endif /* FALSE */
#ifndef TRUE
# define TRUE (!FALSE)
#endif /* TRUE */
#define offset(ptr,member) ((long)(&((ptr)->member))-(long)(ptr))
/************ structure definitions ***************/
/* fontlib directory structures */
struct flib_dirent { char mname[FILENAMELEN]; /* old version */
long size; /* size of pk-module in bytes */
long where; /* position in flib-file */
};
struct new_flib_dirent { char mname[NEWFILENAMELEN]; /* new version */
unsigned short checksum;
long size; /* size of pk-module in bytes */
long where; /* position in flib-file */
char * real_path; /* only for flib internal use!! */
/* real_path won't saved to the flib */
};
union direntry { struct flib_dirent old;
struct new_flib_dirent new;
};
/* internal representation of the flib-directory */
struct dirlist { struct new_flib_dirent dirent;
struct dirlist *next;
};
struct dir { long total;
long alloc;
int version; /* old or new flib */
int is_link;
struct dirlist *dirlist;
char real_name[DOSNAMESIZE];
};
/********* P R O T O T Y P E S ********/
/* main function */
void main Args((int argc, char *argv[]));
/********* local functions **********/
/* print the help */
static void usage Args((char *pname));
/* parse the first argument */
static int decode_args Args((int argc, char **argv,
int *table,
int *extract,
int *create,
int *delete,
int *compress,
int *verbose,
int *rename,
int *test,
int *link,
int *term_input));
/* calculates the length of a module name */
static int module_len(char * name);
/* delete flib with the name "name" and rename the tmpflib to "name" */
/* nr is the number of modules in the flib => nr == 0 --> no flib */
static int insert_name_into_dir Args((char *name,
struct dirlist **dirl,
int version));
/* is module from "test" in "inp1" or "inp2" ? */
static struct dirlist *exist_entry Args((struct dirlist *inp1,
struct dirlist *inp2,
struct dirlist *test));
/* create a dirlist structure entry whith the module-name "name" */
static int read_new_modules Args((int term_input,
int argc,
char **argv,
struct dir *directory,
struct dirlist **start_dirl,
int verbose));
/* read a list of modules from argv or from stdin */
static FILE *open_flib Args((char *name,
char *mode,
struct dir *directory,
short levels));
/* open a flib and test the magic-number */
static int read_dir Args((FILE *f,
struct dir *directory));
/* read the directory from the flib (file-pointer must be on the first dir) */
/* only this directory entries a correct where "where != 0" the others are unused */
static void print_dir Args((struct dir *directory,
char *lib_name,
int verbose));
/* print the contents of the directory */
static int ex_module Args((struct dir *directory,
char *mname,
FILE *flib, int verbose));
/* search a module in the flib and copy it to a new file */
static int create_new_flib Args((struct dir *directory,
char *name,
int verbose));
/* create a complete (new) flib, copy only files into the flib */
static int copy_module Args((char *name,
char *real_path,
FILE *flib,
long *size,
long *where,
unsigned short *check));
/* create a new flib and prepare the directory part */
static FILE *copy_directory Args((struct dir *directory,
char *name,
int verbose));
/* copy a module (file) to the actual position in flib */
static FILE *copy_old_flib Args((struct dir *directory,
FILE *flib,
char *name,
int verbose));
/* copy the modules (from flib) with "where != 0" to flib (tmplib) */
static int append_modules_to_flib Args((struct dir *directory,
FILE *flib,
int verbose));
/* copy the modules (files) with "where == 0" to flib (tmplib) */
static int del_module_from_dir Args((struct dir *directory,
char *name,
int verbose));
/* find a module and delete it from the directory list */
static void copy_tmpflib Args((char *name,
long nr));
/* copy file source to file drain */
static int copy_file Args((char *source,
char *drain));
/* save directory to file */
static int update_dir Args((struct dir *directory,
FILE *flib,
int verbose));
/* extract module name from old and copies it to new */
static void module_name Args((char *old, char *new));
/* update ndir.mname according to strip_path and strip_ext */
static void upd_font_name Args((struct new_flib_dirent * ndir));
/* change module-names in directory */
static int rename_entries Args((struct dir *directory,
struct dirlist *dirl,
int verbose));
/* test all checksums of the fontlibrary */
static void test_flib Args((FILE *flib,
struct dir *directory,
int verbose));
/* read the directory structure */
static int freaddir Args((union direntry *dir,
int version,
FILE *f));
/* read a four byte number <hihi lohi hilo lolo> */
static int freadlong Args((long *buf,
FILE *f));
/* read a two byte number <hi lo> */
static int freadshort Args((unsigned short *buf,
FILE *f));
/* write the directory structure */
static int fwritedir Args((union direntry *dir,
int version,
FILE *f));
/* write a four byte number <hihi lohi hilo lolo> */
static int fwritelong Args((long buf,
FILE *f));
/* write a two byte number <hi lo> */
static int fwriteshort Args((unsigned short buf,
FILE *f));
/* global variables */
int strip_path, strip_ext;
/******************** M A I N ********************/
void main(argc, argv)
int argc;
char *argv[];
{
FILE *flib;
struct dir directory;
char input[256];
int table, extract, create, delete, compress, verbose, rename, test, link, term_input;
int i;
if (argc < 3) {
usage(argv[0]);
exit(5);
}
#ifdef _DCC
expand_args(argc, argv, &argc, &argv); /* expand wildcards */
#endif /* _DCC */
directory.total = directory.alloc = 0;
directory.dirlist = NULL;
directory.version = NEW_VERSION; /* default version */
flib = NULL;
if (!decode_args(argc, argv, &table, &extract, &create, &delete, &compress,
&verbose, &rename, &test, &link, &term_input)) {
usage(argv[0]);
exit(5);
}
if (verbose) {
printf(HEADER,VERSION,MACHINE);
}
/**************** extract **************/
if (extract) {
if ((flib = open_flib(argv[2],OPEN_FOR_READING,&directory,(short)0)) == NULL) {
exit(5);
}
if (!read_dir(flib,&directory)) {
exit(5);
}
if (term_input) {
while (!feof(stdin)) {
if (gets(input) != NULL) {
(void)ex_module(&directory,input,flib,verbose);
}
}
}
else {
if(argc == 3) { /* extract all if no modules specified ++jrb */
struct dirlist *dl;
for(dl = directory.dirlist; dl != NULL; dl = dl->next)
(void)ex_module(&directory,dl->dirent.mname,flib,
verbose);
}
else { /* extract only modules specified */
for (i=3; i<argc; i++) {
(void)ex_module(&directory,argv[i],flib,verbose);
}
}
}
fclose(flib);
flib = NULL;
}
/**************** create **************/
if (create) {
#if (defined(ATARI) && (!(defined(__GNUC__)))) || defined(AMIGA)
if (access(argv[2],6) == 0) { /* read + write */
#else
if (access(argv[2],S_IWRITE | S_IREAD) == 0) { /* read + write */
#endif
struct dirlist *dirl, *start_dirl;
FILE *tmplib;
int nr;
if ((flib = open_flib(argv[2],OPEN_FOR_READING,&directory,(short)0)) == NULL) {
exit(5);
}
if (!read_dir(flib,&directory)) {
exit(5);
}
/* nun noch den Rest anhaengen */
/* internal directory */
for (dirl = directory.dirlist;
dirl != NULL && dirl->next != NULL;
dirl = dirl->next);
nr = read_new_modules(term_input,argc,argv,
&directory,&start_dirl,verbose);
if (dirl == NULL) {
directory.dirlist = start_dirl;
directory.total = nr;
}
else {
dirl->next = start_dirl;
directory.total += nr;
}
directory.alloc += nr;
/* copy old flib with the new directory */
if ((tmplib = copy_old_flib(&directory,flib,argv[2],verbose)) == NULL) {
exit(5);
}
/* append the new modules */
if (!append_modules_to_flib(&directory,tmplib,verbose)) {
exit(5);
}
fclose(tmplib);
fclose(flib);
flib = NULL;
copy_tmpflib(directory.real_name,directory.total);
}
else {
directory.total = read_new_modules(term_input,argc,argv,
&directory,&(directory.dirlist),verbose);
if (!create_new_flib(&directory,argv[2],verbose)) {
exit(5);
}
}
}
/**************** delete **************/
if (delete) {
FILE *tmplib;
if ((flib = open_flib(argv[2],OPEN_FOR_READING,&directory,(short)0)) == NULL) {
exit(5);
}
if (directory.version == OLD_VERSION) {
if (verbose) {
printf("This Option work's only with the new flib-version!\n");
printf("Convert first the flib with \"flib z %s\"\n",argv[2]);
}
else {
fprintf(stderr,"Wrong flib-version!\n");
}
}
if (!read_dir(flib,&directory)) {
exit(5);
}
if (term_input) {
while (!feof(stdin)) {
if (gets(input) != NULL) {
(void)del_module_from_dir(&directory,input,verbose);
}
}
}
else {
if (argc==3) {
if (verbose) {
printf("No module to delete!?!\n");
}
fclose(flib);
flib = NULL;
exit(0);
}
else {
for (i=3; i<argc; i++) {
(void)del_module_from_dir(&directory,argv[i],verbose);
}
}
}
/* copy old flib with the new directory */
if ((tmplib = copy_old_flib(&directory,flib,argv[2],verbose)) == NULL) {
exit(5);
}
/* append the new modules */
if (!append_modules_to_flib(&directory,tmplib,verbose)) {
exit(5);
}
fclose(tmplib);
fclose(flib);
flib = NULL;
copy_tmpflib(directory.real_name,directory.total);
}
/**************** compress **************/
if (compress) {
FILE *tmplib;
if ((flib = open_flib(argv[2],OPEN_FOR_READING,&directory,(short)0)) == NULL) {
exit(5);
}
if (!read_dir(flib,&directory)) {
exit(5);
}
if (directory.version != NEW_VERSION) {
directory.version = NEW_VERSION;
if (verbose) {
printf("Converting old to new version.\n");
}
}
if (verbose) {
printf("Old directory size: %ld, new directory size: %ld.\n",
directory.alloc, directory.total);
}
/* copy old flib */
if ((tmplib = copy_old_flib(&directory,flib,argv[2],verbose)) == NULL) {
exit(5);
}
update_dir(&directory, tmplib, verbose);
fclose(tmplib);
fclose(flib);
flib = NULL;
copy_tmpflib(directory.real_name,directory.total);
}
/**************** rename **************/
if (rename) {
struct dirlist *dirl;
int nr;
if ((flib = open_flib(argv[2],OPEN_FOR_APPEND,&directory,(short)0)) == NULL) {
exit(5);
}
if (directory.version == OLD_VERSION) {
if (verbose) {
printf("This Option work's only with the new flib-version!\n");
printf("Convert first the flib with \"flib z %s\"\n",argv[2]);
}
else {
fprintf(stderr,"Wrong flib-version!\n");
}
}
nr = read_new_modules(term_input,argc,argv,&directory,&dirl,verbose);
if (!read_dir(flib,&directory)) {
exit(5);
}
if (!rename_entries(&directory,dirl,verbose)) {
exit(5);
}
update_dir(&directory, flib, verbose);
fclose(flib);
flib = NULL;
}
/**************** test ***************/
if (test) {
if ((flib = open_flib(argv[2],OPEN_FOR_READING,&directory,(short)0)) == NULL) {
exit(5);
}
if (directory.version == OLD_VERSION) {
if (verbose) {
printf("This Option work's only with the new flib-version!\n");
printf("Convert first the flib with \"flib z %s\"\n",argv[2]);
}
else {
fprintf(stderr,"Wrong flib-version!\n");
}
}
else {
if (directory.alloc == 0 && !read_dir(flib,&directory)) {
exit(5);
}
test_flib(flib,&directory,verbose);
}
fclose(flib);
flib = NULL;
}
/**************** link ***************/
if (link) {
char link_name[DOSNAMESIZE];
if ((flib = fopen(argv[2],OPEN_FOR_WRITING)) == NULL) {
}
else {
if (!fwritelong(LNKMAGIC,flib)) {
perror("*** ");
fprintf(stderr,"*** Can't write to LNK-flib \"%s\"!\n",
argv[2]);
exit(5);
}
link_name[0] = '<';
link_name[1] = '\0';
strcat(link_name,argv[3]);
strcat(link_name,">");
if (fwrite(link_name,sizeof(char),strlen(link_name),flib) != strlen(link_name)) {
perror("*** ");
fprintf(stderr,"*** Can't write to LNK-flib \"%s\"!\n",
argv[2]);
exit(5);
}
fclose(flib);
flib = NULL;
}
}
/**************** table **************/
if (table) {
if (flib == NULL) {
if ((flib = open_flib(argv[2],OPEN_FOR_READING,&directory,(short)0)) == NULL) {
exit(5);
}
if (directory.alloc == 0 && !read_dir(flib,&directory)) {
exit(5);
}
}
print_dir(&directory,argv[2],verbose);
fclose(flib);
}
} /* main */
/* print the help */
static void usage(pname)
char *pname;
{
fprintf(stderr,HEADER,VERSION,MACHINE);
fprintf(stderr,"usage: %s c|a|x|d|z|p|l|t[v|s|e] library [-|[modules]*]\n",pname);
fprintf(stderr,"\tc,a : create library / add (replace) module(s) to (in) library,\n");
fprintf(stderr,"\tx : extract module(s) from library,\n");
fprintf(stderr,"\td : delete module(s) in library,\n");
fprintf(stderr,"\tt : print table,\n");
fprintf(stderr,"\tr : rename module(s) in library,\n");
fprintf(stderr,"\tz : create new flib from old flib,\n");
fprintf(stderr,"\tp : test checksums of all modules,\n");
fprintf(stderr,"\tl : create a flib link (second arg is the link destination),\n");
fprintf(stderr,"\ts : strip path (only with c,a),\n");
fprintf(stderr,"\te : strip extension (only with c,a),\n");
fprintf(stderr,"\tv : verbose mode,\n");
fprintf(stderr,"\t? : print this help,\n");
fprintf(stderr,"\t- : read module name(s) from stdin.\n");
}
/* parse the first argument */
static int decode_args(argc, argv, table, extract, create,
delete, compress, verbose, rename, test, link, term_input)
int argc;
char **argv;
int *table, *extract, *create, *delete, *compress, *verbose,
*rename, *test, *link, *term_input;
{
char *flags;
int c;
*table = *extract = *create = *delete = *compress = *verbose =
*rename = *test = *link = *term_input = FALSE;
strip_path = strip_ext = FALSE;
flags = argv[1];
if (*flags == '-') {
flags++;
}
c = 0;
for (; *flags != '\0'; flags++) {
switch (*flags) {
case 'c':
case 'a': *create = TRUE; c++; break;
case 'x': *extract = TRUE; c++; break;
case 'd': *delete = TRUE; c++; break;
case 'z': *compress = TRUE; c++; break;
case 'r': *rename = TRUE; c++; break;
case 'l': *link = TRUE; c++; break;
case 'p': *test = TRUE; break;
case 't': *table = TRUE; break;
case 's': strip_path = TRUE; break;
case 'e': strip_ext = TRUE; break;
case 'v': *verbose = TRUE; break;
case '?': return FALSE;
default : fprintf(stderr, "*** Unknown flag '%c'!\n",*flags);
return FALSE;
}
}
if (c >= 2) {
fprintf(stderr,"*** The flags 'c' 'x' 'd' 'z' 'r' 'l' are mutual exclusive!\n");
return FALSE;
}
if (!(*extract || *create || *delete || *table || *compress || *rename || *test || *link)) {
fprintf(stderr,"*** Missing one of the flags 'c' 'x' 'd' 'z' 't' 'p' 'l'!\n");
return FALSE;
}
if ((strip_path || strip_ext) && !*create) {
fprintf(stderr,"*** Use 's' and 'e' only with 'c' or 'a'!\n");
return FALSE;
}
if (*link && argc != 4) {
fprintf(stderr,"*** Incorrect number of arguments!\n");
return FALSE;
}
if (argc > 3 && strcmp(argv[3],"-") == 0) {
*term_input = TRUE;
if (*verbose && (*create || *extract || *delete || *rename)) {
printf("Reading module names from standard input.\n");
}
}
return TRUE;
}
/* delete flib with the name "name" and rename the tmpflib to "name" */
/* nr is the number of modules in the flib => nr == 0 --> no flib */
static void copy_tmpflib(name, nr)
char *name;
long nr;
{
if (remove(name) != 0) {
perror("*** ");
fprintf(stderr,"*** Can't remove flib \"%s\"!\n",name);
}
if (nr > 0) {
if (rename(TMPFLIB,name) != 0) {
if (!copy_file(TMPFLIB,name)) {
perror("*** ");
fprintf(stderr,"*** Can't rename temporary flib \"%s\" to \"%s\"!\n",
TMPFLIB,name);
}
if (remove(TMPFLIB) != 0) {
perror("*** ");
fprintf(stderr,"*** Can't remove temporary flib \"%s\"!\n",TMPFLIB);
}
}
}
else {
if (remove(TMPFLIB) != 0) {
perror("*** ");
fprintf(stderr,"*** Can't remove temporary flib \"%s\"!\n",TMPFLIB);
}
}
}
/* copy file source to file drain */
static int copy_file(source, drain)
char *source;
char *drain;
{
FILE *sf, *df;
long len;
if ((sf = fopen(source,OPEN_FOR_READING)) == NULL) {
return FALSE;
}
if ((df = fopen(drain,OPEN_FOR_WRITING)) == NULL) {
fclose(sf);
return FALSE;
}
while ((len = fread(buffer,sizeof(char),BUFSIZE,sf)) == BUFSIZE) {
if (fwrite(buffer,sizeof(char),BUFSIZE,df) != BUFSIZE) {
fclose(sf);
fclose(df);
return FALSE;
}
}
if (len > 0) {
if (fwrite(buffer,sizeof(char),len,df) != len) {
fclose(sf);
fclose(df);
return FALSE;
}
}
fclose(sf);
fclose(df);
return TRUE;
}
/* create a dirlist structure entry whith the module-name "name" */
static int insert_name_into_dir(name,dirl,version)
char *name;
struct dirlist **dirl;
int version;
{
char newpath[NEWFILENAMELEN];
int j;
int len;
len = module_len(name); /* length without path-extension */
module_name(name, newpath); /* extract path-extension */
if ((version == NEW_VERSION && len > NEWFILENAMELEN-1) ||
(version == OLD_VERSION && len > FILENAMELEN-1)) {
fprintf(stderr,"*** Module name \"%s\" too long!\n",name);
return FALSE;
}
if ((*dirl = (struct dirlist *)
malloc(sizeof(struct dirlist))) == NULL) {
fprintf(stderr,"*** No memory for internal flib directory!\n");
exit(5);
}
for (j=0; j<NEWFILENAMELEN; j++) { /* clear the string */
(*dirl)->dirent.mname[j] = '\0';
}
strncpy((*dirl)->dirent.mname,newpath,NEWFILENAMELEN);
(*dirl)->dirent.size = 0L;
(*dirl)->dirent.where = 0L;
(*dirl)->next = NULL;
if (((*dirl)->dirent.real_path = strdup(name)) == NULL) {
fprintf(stderr,"*** No memory for internal flib directory!\n");
exit(5);
}
return TRUE;
}
/* calculates the length of a module name */
static int module_len(name)
char * name;
{
int len;
char * ptr;
len = strlen(name);
if (strip_path) {
ptr = strrchr(name, '/');
#ifdef AMIGA
if (!ptr) ptr = strchr(name, ':');
#endif
if (ptr) len -= (ptr-name+1);
}
if (strip_ext) {
ptr = strrchr(name, '.');
if (ptr) len -= strlen(ptr);
}
return len;
}
/* is module from "test" in "inp1" or "inp2" ? */
static struct dirlist *exist_entry(inp1, inp2, test)
struct dirlist *inp1, *inp2;
struct dirlist *test; /* only one entry in list */
{
char *name = test->dirent.mname;
for (; inp1 != NULL && strcmp(name,inp1->dirent.mname) != 0; inp1 = inp1->next);
if (inp1 != NULL) {
return inp1;
}
for (; inp2 != NULL && strcmp(name,inp2->dirent.mname) != 0; inp2 = inp2->next);
if (inp2 != NULL) {
return inp2;
}
return NULL;
}
/* read a list of modules from argv or from stdin */
static int read_new_modules(term_input,argc,argv,directory,start_dirl,verbose)
int term_input;
int argc;
char **argv;
struct dir *directory;
struct dirlist **start_dirl;
int verbose;
{
int nr_modules, i;
struct dirlist *dirl, *old_dirl, *find_old;
char input[256];
old_dirl = dirl = NULL;
nr_modules = 0;
*start_dirl = NULL;
if (term_input) {
while (!feof(stdin)) {
if (gets(input) != NULL) {
if (insert_name_into_dir(input, &dirl,directory->version)) {
if ((find_old = exist_entry(directory->dirlist,
*start_dirl,dirl)) != NULL) {
/* the module is already in the lib */
/* replace it */
find_old->dirent.where = 0L;
/* now it must new inserted */
if (verbose) {
printf("Replacing module \"%s\".\n",
find_old->dirent.mname);
}
}
else {
nr_modules++;
if (old_dirl == NULL) {
*start_dirl = dirl;
}
else {
old_dirl->next = dirl;
}
old_dirl = dirl;
}
}
}
}
}
else {
for (i=3; i<argc; i++) {
if (insert_name_into_dir(argv[i], &dirl, directory->version)) {
if ((find_old = exist_entry(directory->dirlist,
*start_dirl,dirl)) != NULL) {
/* the module is already in the lib */
/* replace it */
find_old->dirent.where = 0L;
/* now it must new inserted */
if (verbose) {
printf("Replacing module \"%s\".\n",
find_old->dirent.mname);
}
}
else {
nr_modules++;
if (old_dirl == NULL) {
*start_dirl = dirl;
}
else {
old_dirl->next = dirl;
}
old_dirl = dirl;
}
}
}
}
if (dirl != NULL) {
dirl->next = NULL;
}
return nr_modules;
}
/* open a flib and test the magic-number */
static FILE *open_flib(name,mode,directory,levels)
char *name;
char *mode;
struct dir *directory;
short levels;
{
static char link_name[DOSNAMESIZE];
char newname[DOSNAMESIZE], *ptr, *p;
FILE *f;
long magic;
directory->is_link = FALSE;
directory->real_name[0] = '\0';
if ((f = fopen(name,mode)) == NULL) {
fprintf(stderr,"*** Can't open library \"%s\"!\n",name);
return NULL;
}
if (!freadlong(&magic,f) ||
(magic != LIBMAGIC && magic != OLD_LIBMAGIC && magic != LNKMAGIC)) {
fclose(f);
fprintf(stderr,"*** File \"%s\" isn't a font library!\n",name);
return NULL;
}
if (magic == LNKMAGIC) {
(void)fread(link_name,sizeof(char),DOSNAMESIZE,f);
fclose(f);
if (link_name[0] != '<') {
fprintf(stderr,"*** Illegal flib-link \"%s\"!\n",name);
return NULL;
}
ptr = strrchr(link_name,'>');
if (ptr == NULL) {
fprintf(stderr,"*** Illegal flib-link \"%s\"!\n",name);
return NULL;
}
levels++;
if (levels > MAXLINKLEVELS) {
fprintf(stderr,"*** To many link levels!\n");
return NULL;
}
*ptr = '\0';
ptr = link_name;
ptr++;
strcpy(newname, name);
/* is 'ptr' (target of the link) a relative path ? */
if (
#ifdef AMIGA
strchr(ptr,':') == NULL
#else
# ifdef ATARI
!((*ptr & 0x40) == 0x40 && *(ptr + 1) == ':')
# else
*ptr != '/'
# endif
#endif
) {
/* if yes, take the dir of the link-file and append the target name */
if ((p = strrchr(newname,'/')) == NULL) {
p = strchr(newname,':');
/* if the link-file has no dir -> ok, we are already in the right dir */
}
if (p != NULL) {
*(p+1) = '\0';
strcat(newname, ptr);
ptr = strcpy(link_name, newname);
}
}
f = open_flib(ptr,mode,directory,levels);
directory->is_link = TRUE;
}
else {
if (magic == LIBMAGIC) {
directory->version = NEW_VERSION;
}
else {
directory->version = OLD_VERSION;
}
strcpy(directory->real_name,name);
}
return f;
}
/* read the directory from the flib (file-pointer must be on the first dir) */
/* only this directory entries a correct where "where != 0" the others are unused */
static int read_dir(f,directory)
FILE *f;
struct dir *directory;
{
long alloc;
union direntry dir;
struct dirlist *direntr, *old_direntry;
int i, j, nr;
if (!freadlong(&alloc,f)) {
fprintf(stderr,"*** Error while reading internal flib directory!\n");
return FALSE;
}
direntr = old_direntry = NULL;
for (i=0, nr=0; i<alloc && !feof(f); i++) {
if (!freaddir(&dir,directory->version,f)) {
fprintf(stderr,"*** Error while reading internal flib directory!\n");
return FALSE;
}
if ((directory->version == NEW_VERSION && dir.new.where != 0) || /* used entry */
(directory->version == OLD_VERSION && dir.old.where != 0)) {
nr++;
if ((direntr = (struct dirlist *)
malloc(sizeof(struct dirlist))) == NULL) {
fprintf(stderr,"*** No memory for internal flib directory!\n");
return FALSE;
}
direntr->dirent.real_path = NULL;
for (j=0; j<NEWFILENAMELEN; j++) { /* clear the string */
direntr->dirent.mname[j] = '\0';
}
if (old_direntry == NULL ) {
directory->dirlist = direntr;
}
else {
old_direntry->next = direntr;
}
if (directory->version == NEW_VERSION) {
direntr->dirent = dir.new;
}
else {
strncpy(direntr->dirent.mname,dir.old.mname,FILENAMELEN);
direntr->dirent.size = dir.old.size;
direntr->dirent.where = dir.old.where;
direntr->dirent.checksum = 0;
}
old_direntry = direntr;
}
}
if (direntr != NULL) {
direntr->next = NULL;
}
directory->total = nr;
directory->alloc = alloc;
if (nr == 0) {
directory->dirlist = NULL;
}
return TRUE;
}
/* print the contents of the directory */
static void print_dir(directory, lib_name, verbose)
struct dir *directory;
char *lib_name;
int verbose;
{
struct dirlist *temp;
if (verbose) {
if (directory->total == 1) {
printf ("Library contains one module. ");
}
else {
printf ("Library contains %ld modules. ",directory->total);
}
if (directory->alloc == 1) {
printf ("Directory size is one module.\n");
}
else {
printf ("Directory size is %ld modules.\n",directory->alloc);
}
if (directory->is_link) {
printf ("The library \"%s\" is a link to \"%s\"!\n",
lib_name, directory->real_name);
}
if (directory->version == OLD_VERSION) {
printf ("WARNING: That's an old library-version!\n");
}
printf ("\n Module name Size Position\n");
printf (" --------------------- ------ --------\n");
for (temp = directory->dirlist; temp != NULL; temp = temp->next) {
printf (" %-21s %6ld %8ld\n", temp->dirent.mname,
temp->dirent.size, temp->dirent.where);
}
printf("\n");
}
else {
for (temp = directory->dirlist; temp != NULL; temp = temp->next) {
puts(temp->dirent.mname);
}
}
}
/* search a module in the flib and copy it to a new file */
static int ex_module(directory, mname, flib, verbose)
struct dir *directory;
char *mname;
FILE *flib;
int verbose;
{
struct dirlist *temp;
FILE *module;
int i, j, count;
unsigned short check;
if (directory == NULL || flib == NULL) {
fprintf(stderr,"*** Internal error!\n");
return FALSE;
}
/* find the module */
for (temp = directory->dirlist; temp != NULL
&& strcmp(temp->dirent.mname,mname) != 0; temp = temp->next);
if (temp == NULL) {
fprintf(stderr,"*** Can't find module \"%s\"!\n",mname);
return FALSE;
}
if (verbose) {
printf("Extracting module %s \t(%ld bytes).\n",mname, temp->dirent.size);
}
if (fseek(flib,temp->dirent.where,0) != 0) {
perror("*** ");
fprintf(stderr,"*** Error during fseek!\n");
return FALSE;
}
if ((module = fopen(mname,OPEN_FOR_WRITING)) == NULL) {
fprintf(stderr,"*** Can't create file \"%s\"!\n",mname);
return FALSE;
}
count = temp->dirent.size / BUFSIZE;
check = 0;
for (i=0; i<count; i++) {
if (fread(buffer,sizeof(char),BUFSIZE,flib)!=BUFSIZE) {
fclose(module);
fprintf(stderr,"*** Can't read from flib!\n");
return FALSE;
}
for (j=0; j<BUFSIZE; j++) {
check += (unsigned short)buffer[j];
}
if (fwrite(buffer,sizeof(char),BUFSIZE,module) != BUFSIZE) {
fclose(module);
fprintf(stderr,"*** Can't write to module %s!\n",mname);
return FALSE;
}
}
i = temp->dirent.size - count * BUFSIZE; /* copy rest */
if (i > 0) {
if (fread(buffer,sizeof(char),i,flib) != i) {
fclose(module);
fprintf(stderr,"*** Can't read from flib!\n");
return FALSE;
}
for (j=0; j<i; j++) {
check += buffer[j];
}
if (fwrite(buffer,sizeof(char),i,module) != i) {
fclose(module);
fprintf(stderr,"*** Can't write to module %s!\n",mname);
return FALSE;
}
}
fclose(module);
if (directory->version != OLD_VERSION && check != temp->dirent.checksum) {
fprintf(stderr,"*** WARNING: Module \"%s\" extracted with wrong checksum!\n",
mname);
}
return TRUE;
}
/* create a complete (new) flib, copy only files into the flib */
static int create_new_flib(directory, name, verbose)
struct dir *directory;
char *name;
int verbose;
{
FILE *flib;
struct dirlist *dirl;
long size=0, where=0;
unsigned short check;
if ((flib = copy_directory(directory, name, verbose)) == NULL) {
return FALSE;
}
/* module abspeichern */
for (dirl = directory->dirlist; dirl != NULL; dirl = dirl->next) {
if (verbose) {
printf("Copying module \"%s\"\t... ",dirl->dirent.mname);
}
if (!copy_module(dirl->dirent.mname,dirl->dirent.real_path,flib,&size,&where,&check)) {
fprintf(stderr,"\n*** Can't copy module \"%s\" to library!\n",
dirl->dirent.mname);
return FALSE;
}
if (verbose) {
printf("ok. \t(%ld bytes at %ld)\n",size,where);
}
dirl->dirent.size = size;
dirl->dirent.where = where;
dirl->dirent.checksum = check;
}
update_dir(directory, flib, verbose);
return TRUE;
}
/* create a new flib and prepare the directory part */
static FILE *copy_directory(directory, name, verbose)
struct dir *directory;
char *name;
int verbose;
{
FILE *flib;
long magic = (directory->version == NEW_VERSION) ? LIBMAGIC : OLD_LIBMAGIC;
struct dirlist *dirl;
union direntry dir;
if ((flib = fopen(name,OPEN_FOR_WRITING)) == NULL) {
fprintf(stderr,"*** Can't open destination library!\n");
return NULL;
}
if (!fwritelong(magic,flib) || !fwritelong(directory->total,flib)) {
fprintf(stderr,"*** Can't write to destination library!\n");
return NULL;
}
/* directory anlegen */
if (verbose) {
printf("Creating internal flib directory\t... ");
}
for (dirl = directory->dirlist; dirl != NULL; dirl = dirl->next) {
if (directory->version == NEW_VERSION) {
dir.new = dirl->dirent;
}
else {
strncpy(dir.old.mname,dirl->dirent.mname,FILENAMELEN);
dir.old.size = dirl->dirent.size;
dir.old.where = dirl->dirent.where;
}
if (!fwritedir(&dir,directory->version,flib)) {
fprintf(stderr,"*** Can't write to destination library!\n");
return NULL;
}
}
if (verbose) {
printf("ok.\n");
}
return flib;
}
/* copy a module (file) to the actual position in flib */
static int copy_module(name, real_path, flib, size, where, check)
char *name;
char *real_path;
FILE *flib;
long *size, *where;
unsigned short *check;
{
FILE *module;
int len, i;
char *open_name;
if (real_path != NULL) {
open_name = real_path;
}
else {
open_name = name;
}
if ((module = fopen(open_name,OPEN_FOR_READING)) == NULL) {
return FALSE;
}
*size = 0;
*where = ftell(flib);
*check = 0;
while ((len = fread(buffer,sizeof(char),BUFSIZE,module)) == BUFSIZE) {
if (fwrite(buffer,sizeof(char),BUFSIZE,flib) != BUFSIZE) {
fclose(module);
return FALSE;
}
*size += BUFSIZE;
for (i=0; i<BUFSIZE; i++) {
*check += (unsigned short)buffer[i];
}
}
if (len > 0) {
if (fwrite(buffer,sizeof(char),len,flib) != len) {
fclose(module);
return FALSE;
}
*size += len;
for (i=0; i<len; i++) {
*check += (unsigned short)buffer[i];
}
}
fclose(module);
return TRUE;
}
/* copy the modules (from flib) with "where != 0" to flib (tmplib) */
static FILE *copy_old_flib(directory, flib, name, verbose)
struct dir *directory;
FILE *flib;
char *name;
int verbose;
{
FILE *tmplib;
struct dirlist *dirl;
long where;
int i, j;
long len ,count;
unsigned short check;
if ((tmplib = copy_directory(directory, TMPFLIB, verbose)) == NULL) {
return NULL;
}
/* module copy */
for (dirl = directory->dirlist; dirl != NULL; dirl = dirl->next) {
if (dirl->dirent.where != 0L) {
if (verbose) {
printf("Copying module \"%s\"\t... ",dirl->dirent.mname);
}
if (fseek(flib,dirl->dirent.where,0) != 0) {
perror("*** ");
fprintf(stderr,"*** Error during fseek!\n");
return NULL;
}
where = ftell(tmplib);
count = dirl->dirent.size / BUFSIZE;
check = 0;
for (i=0; i<count; i++) {
if (fread(buffer,sizeof(char),BUFSIZE,flib)!=BUFSIZE) {
fclose(tmplib);
fprintf(stderr,"*** Can't read from flib!\n");
return NULL;
}
for (j=0; j<BUFSIZE; j++) {
check += (unsigned short)buffer[j];
}
if (fwrite(buffer,sizeof(char),BUFSIZE,tmplib) != BUFSIZE) {
fclose(tmplib);
fprintf(stderr,"*** Can't write to temporary flib!\n");
return NULL;
}
}
len = dirl->dirent.size - count * BUFSIZE;
if (len > 0) {
if (fread(buffer,sizeof(char),(int)len,flib) != len) {
fclose(tmplib);
fprintf(stderr,"*** Can't read from flib!\n");
return NULL;
}
for (j=0; j<len; j++) {
check += (unsigned short)buffer[j];
}
if (fwrite(buffer,sizeof(char),(int)len,tmplib) != len) {
fclose(tmplib);
fprintf(stderr,"*** Can't write to temporary flib!\n");
return NULL;
}
}
dirl->dirent.where = where;
dirl->dirent.checksum = check;
if (verbose) {
printf("ok.\n");
}
}
}
return tmplib;
}
/* copy the modules (files) with "where == 0" to flib (tmplib) */
static int append_modules_to_flib(directory, flib, verbose)
struct dir *directory;
FILE *flib;
int verbose;
{
struct dirlist *dirl;
long size, where;
unsigned short check;
/* module abspeichern */
if (fseek(flib,0L,2) != 0) { /* end of file */
perror("*** ");
fprintf(stderr,"*** Error during fseek!\n");
return 0;
}
for (dirl = directory->dirlist; dirl != NULL; dirl = dirl->next) {
if (dirl->dirent.where == 0L) {
if (verbose) {
printf("Copying module \"%s\"\t... ",dirl->dirent.mname);
}
if (!copy_module(dirl->dirent.mname,dirl->dirent.real_path,flib,&size,&where,&check)) {
fprintf(stderr,"\n*** Can't copy module \"%s\" to library!\n");
return FALSE;
}
if (verbose) {
printf("ok. \t(%ld bytes at %ld)\n",size,where);
}
dirl->dirent.size = size;
dirl->dirent.where = where;
dirl->dirent.checksum = check;
}
}
return update_dir(directory, flib, verbose);
}
/* find a module and delete it from the directory list */
static int del_module_from_dir(directory, name, verbose)
struct dir *directory;
char *name;
int verbose;
{
struct dirlist *temp, *parent;
if (directory == NULL) {
fprintf(stderr,"*** Internal error!\n");
return FALSE;
}
/* find the module */
for (temp = directory->dirlist, parent = NULL; temp != NULL
&& strcmp(temp->dirent.mname,name) != 0;
parent = temp, temp = temp->next);
if (temp == NULL) {
fprintf(stderr,"*** Can't find module \"%s\"!\n",name);
return FALSE;
}
/* delete module from directory-list */
if (parent == NULL) {
directory->dirlist = temp->next;
}
else {
parent->next = temp->next;
}
free(temp);
directory->alloc = --directory->total;
return TRUE;
}
/* save directory to file */
static int update_dir(directory, flib, verbose)
struct dir *directory;
FILE *flib;
int verbose;
{
struct dirlist *dirl;
union direntry dir;
/* directory size-where */
if (verbose) {
printf("Updating internal flib directory\t... ");
}
if (fseek(flib,8L,0) != 0) {
perror("*** ");
fprintf(stderr,"*** Can't fseek?!\n");
return FALSE;
}
for (dirl = directory->dirlist; dirl != NULL; dirl = dirl->next) {
if (directory->version == NEW_VERSION) {
dir.new = dirl->dirent;
upd_font_name(&dir.new);
}
else {
strncpy(dir.old.mname,dirl->dirent.mname,FILENAMELEN);
dir.old.size = dirl->dirent.size;
dir.old.where = dirl->dirent.where;
}
if (!fwritedir(&dir,directory->version,flib)) {
fprintf(stderr,"*** Can't write to destination library!\n");
return FALSE;
}
}
if (verbose) {
printf("ok.\n");
}
return TRUE;
}
/* extract module name from old and copies it to new */
/* new must point to a char array of at least MEWFILENAMELEN chars */
static void module_name(old, new)
char *old, *new;
{
char * ptr;
if (strip_path) {
ptr = strrchr(old, '/');
#ifdef AMIGA
if (!ptr) ptr = strchr(old, ':');
#endif
if (ptr) {
/* delete path */
ptr++;
strncpy(new, ptr, NEWFILENAMELEN);
}
else {
strncpy(new, old, NEWFILENAMELEN);
}
}
else {
strncpy(new, old, NEWFILENAMELEN);
}
if (strip_ext) {
ptr = strrchr(new, '.');
if (ptr) {
/* delete extension */
char * ptr2;
for (ptr2 = ptr; ptr2 < new+NEWFILENAMELEN; ptr2++) {
*ptr2 = '\0';
}
}
}
}
/* Change ndir.mname[] according to the flags strip_path and strip_ext */
static void upd_font_name(ndir)
struct new_flib_dirent * ndir;
{
char newpath[NEWFILENAMELEN];
module_name(ndir->mname, newpath);
strncpy(ndir->mname, newpath, NEWFILENAMELEN);
}
/* change module-names in directory */
/* if dirl empty then change all names in directory */
static int rename_entries(directory,dirl,verbose)
struct dir *directory;
struct dirlist *dirl;
int verbose;
{
struct dirlist *entry, *found;
char str[256];
int allowed_length = (directory->version == NEW_VERSION)
? NEWFILENAMELEN
: FILENAMELEN;
if (dirl == NULL) { /* no modules -> change all names */
for (entry = directory->dirlist; entry != NULL; entry = entry->next) {
do {
printf("Old name: %s, change it to: ",entry->dirent.mname);
if (gets(str) == NULL) {
fprintf(stderr,"\nUnexpected end of \"stdin\"!?\n");
return FALSE;
}
if (strlen(str) > allowed_length) {
fprintf(stderr,"New name too long!\n");
}
} while (strlen(str) > allowed_length);
if (str[0] != '\0') {
if (verbose) {
printf("%s ---> %s\n",entry->dirent.mname,str);
}
strcpy(entry->dirent.mname,str);
}
}
}
else { /* change only the names of the given modules */
for (entry = dirl; entry != NULL; entry = entry->next) {
if ((found = exist_entry(NULL,directory->dirlist,entry)) != NULL) {
do {
printf("Old name: %s, change it to: ",
found->dirent.mname);
if (gets(str) == NULL) {
fprintf(stderr,"\nUnexpected end of \"stdin\"!?\n");
return FALSE;
}
if (strlen(str) > allowed_length) {
fprintf(stderr,"New name too long!\n");
}
} while (strlen(str) > allowed_length);
if (str[0] != '\0') {
if (verbose) {
printf("%s ---> %s\n",found->dirent.mname,str);
}
strcpy(found->dirent.mname,str);
}
}
}
}
return TRUE;
}
/* test all checksums of the fontlibrary */
static void test_flib(flib, directory, verbose)
FILE *flib;
struct dir *directory;
int verbose;
{
int i, j;
struct dirlist *dirl;
unsigned short check;
long count, len;
for (dirl = directory->dirlist; dirl != NULL; dirl = dirl->next) {
if (dirl->dirent.where != 0L) {
if (verbose) {
printf("Checking module \"%s\"\t... ",dirl->dirent.mname);
}
if (fseek(flib,dirl->dirent.where,0) != 0) {
perror("*** ");
fprintf(stderr,"*** Error during fseek!\n");
return;
}
count = dirl->dirent.size / (long)BUFSIZE;
check = 0;
for (i=0; i<count; i++) {
if (fread(buffer,sizeof(char),BUFSIZE,flib)!=BUFSIZE) {
fprintf(stderr,"*** Can't read from flib!\n");
return;
}
for (j=0; j<BUFSIZE; j++) {
check += (unsigned short)buffer[j];
}
}
len = dirl->dirent.size - count * (long)BUFSIZE;
if (len > 0) {
if (fread(buffer,sizeof(char),(int)len,flib) != len) {
fprintf(stderr,"*** Can't read from flib!\n");
return;
}
for (j=0; j<len; j++) {
check += (unsigned short)buffer[j];
}
}
if (dirl->dirent.checksum == check) {
if (verbose) {
printf("ok.\n");
}
}
else {
if (verbose) {
printf("ERROR (expected %u, found %u)\n",
dirl->dirent.checksum, check);
}
else {
fprintf(stderr,
"ERROR: module \"%s\" (expected %u, found %u)\n",
dirl->dirent.mname, dirl->dirent.checksum, check);
}
}
}
}
}
/* read the directory structure */
static int freaddir(dir,version,f)
union direntry *dir;
int version;
FILE *f;
{
if (version == OLD_VERSION) {
if (fread(dir->old.mname,FILENAMELEN,1,f) != 1) {
return FALSE;
}
dir->new.mname[FILENAMELEN] = '\0';
if (!freadlong(&(dir->old.size),f)) {
return FALSE;
}
if (!freadlong(&(dir->old.where),f)) {
return FALSE;
}
}
else {
if (fread(dir->new.mname,1,NEWFILENAMELEN,f) != NEWFILENAMELEN) {
return FALSE;
}
if (!freadshort(&(dir->new.checksum),f)) {
return FALSE;
}
if (!freadlong(&(dir->new.size),f)) {
return FALSE;
}
if (!freadlong(&(dir->new.where),f)) {
return FALSE;
}
}
return TRUE;
}
/* read a four byte number <hihi lohi hilo lolo> */
static int freadlong(buf,f)
long *buf;
FILE *f;
{
unsigned char b[4];
if (fread((char *)b,1,4,f) != 4) {
return FALSE;
}
*buf = (long)(((unsigned long)b[0]) << 24) | (((unsigned long)b[1]) << 16) |
(((unsigned long)b[2]) << 8) | ((unsigned long)b[3]);
return TRUE;
}
/* read a two byte number <hi lo> */
static int freadshort(buf,f)
unsigned short *buf;
FILE *f;
{
unsigned char b[2];
if (fread((char *)b,1,2,f) != 2) {
return FALSE;
}
*buf = (unsigned short) (((unsigned short)b[0]) << 8) | ((unsigned short)b[1]);
return TRUE;
}
/* write the directory structure */
static int fwritedir(dir,version,f)
union direntry *dir;
int version;
FILE *f;
{
if (version == OLD_VERSION) {
if (fwrite(dir->new.mname,NEWFILENAMELEN,1,f) != 1) {
return FALSE;
}
if (!fwritelong(dir->new.size,f)) {
return FALSE;
}
if (!fwritelong(dir->new.where,f)) {
return FALSE;
}
}
else {
if (fwrite(dir->new.mname,NEWFILENAMELEN,1,f) != 1) {
return FALSE;
}
if (!fwriteshort(dir->new.checksum,f)) {
return FALSE;
}
if (!fwritelong(dir->new.size,f)) {
return FALSE;
}
if (!fwritelong(dir->new.where,f)) {
return FALSE;
}
}
return TRUE;
}
/* write a four byte number <hihi lohi hilo lolo> */
static int fwritelong(buf,f)
long buf;
FILE *f;
{
unsigned char b[4];
b[0] = (unsigned char)(((unsigned long)buf & 0xFF000000L) >> 24);
b[1] = (unsigned char)(((unsigned long)buf & 0x00FF0000L) >> 16);
b[2] = (unsigned char)(((unsigned long)buf & 0x0000FF00L) >> 8);
b[3] = (unsigned char) ((unsigned long)buf & 0x000000FFL);
if (fwrite((char *)b,1,4,f) != 4) {
return FALSE;
}
return TRUE;
}
/* write a two byte number <hi lo> */
#ifdef ANSI
static int fwriteshort(unsigned short buf, FILE *f)
#else
static int fwriteshort(buf,f)
unsigned short buf;
FILE *f;
#endif /* ANSI */
{
unsigned char b[2];
b[0] = (unsigned char)(((unsigned long)buf & 0x0000FF00L) >> 8);
b[1] = (unsigned char) ((unsigned long)buf & 0x000000FFL);
if (fwrite((char *)b,1,2,f) != 2) {
return FALSE;
}
return TRUE;
}